package com.moody.calculator;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.moody.hibernate.domain.ReportData;

public class PublicFinancialIndexCalculator {
	private static final Logger log = LoggerFactory.getLogger(PublicFinancialIndexCalculator.class);

	private Map<String,Double> currentMap = new HashMap<String,Double>();     //今年
	private Map<String,Double> lastMap = new HashMap<String,Double>();		//去年
	private Map<String,Double> resultMap = new LinkedHashMap<String,Double>();
	private List<ReportData> reportDataList1;
	private List<ReportData> reportDataList2;
	
	public PublicFinancialIndexCalculator(List<ReportData> reportDataList1, List<ReportData> reportDataList2){
		this.reportDataList1 = reportDataList1;
		this.reportDataList2 = reportDataList2;
	}

	//将数据存入map中，包含所有计算财务指标所需要的数据
	public void loadData(){
		if(reportDataList1!=null){
			for(ReportData  rd : reportDataList1){
				currentMap.put(rd.getReportItemNo(), rd.getItemValue());
			}
		}
		if(reportDataList2!=null){
			for(ReportData rd : reportDataList2){
				lastMap.put(rd.getReportItemNo(), rd.getItemValue());
			}
		}
	}
	
	public void computeIndex(){
		//最好是多线程处理
		PublicFinancialIndexCalculator fic = new PublicFinancialIndexCalculator(reportDataList1,reportDataList2);
		fic.loadData();
		Method[] methods = PublicFinancialIndexCalculator.class.getDeclaredMethods();
		for(Method  method : methods){
			String name = method.getName();
			//抽取所有以calculate的方法，表示是计算公式
			if(name.startsWith("calculate")){
				try {
					//reportData名
					name = name.substring("calculate".length(), name.length());
					resultMap.put(name, (Double) method.invoke(fic));
				} catch (Exception e) {
					log.error("该项计算有误",e);
				} 
			}
		}
	}
	
	public Map<String,Double> getResultMap(){
		return resultMap;
	}
	
	/*
	 * 以下为所有的事业单位的财务指标计算公式
	 */
	
	//判断double类型是否为0
	public Boolean isZero(Double data){
		if(data >10E-6 || data <-(10E-6))
			return false;
		else
			return true;
	}
	
	//总收入(百万)
	public Double calculatePFR001(){
		Double PIS013 = currentMap.get("PIS013");
		
		if(PIS013 != null )
			return PIS013/1000000;
		else{
			log.error("数据项不存在或分母为空");
			return null;
		}
	}
	//总收入增长率
	public Double calculatePFR002(){
		Double PBS059 = currentMap.get("PBS059");
		Double lastPBS059 = lastMap.get("PBS059");
		
		if(PBS059 != null && lastPBS059!=null && !isZero(PBS059))
			return (1-(lastPBS059/PBS059)) ;
		else
			return null;
	}
	
	//经费自给率: （事业收入+经营收入+附属单位缴款+其他收入）/（事业支出+经营支出）×100％
	public Double calculatePFR003(){		
		Double PIS005 = currentMap.get("PIS005");//事业收入
		Double PIS009 = currentMap.get("PIS009");//经营收入
		Double PIS004 = currentMap.get("PIS004");//附属单位缴款
		Double PIS007 = currentMap.get("PIS007");//其他收入
		Double PIS018 = currentMap.get("PIS018");//事业支出
		Double PIS041 = currentMap.get("PIS024");//经营支出

		
		if(PIS005 != null && PIS009 != null && PIS004 != null && PIS007 != null && 
				PIS018 != null && PIS041 != null && !isZero(PIS018 + PIS041))
			return (PIS005+PIS009+PIS004+PIS007)/(PIS018 + PIS041);
		else
			return null;
	}
	
	//	收支比率
	public Double calculatePFR004(){
		Double PIS013 = currentMap.get("PIS013");
		Double PIS030 = currentMap.get("PIS030");
		
		if(PIS013 != null && PIS030 !=null && !isZero(PIS030))
			return PIS013 / PIS030;
		else
			return null;
	}
	
	//	收支结余率
	public Double calculatePFR005(){
		Double PIS005 = currentMap.get("PIS005");//事业收入
		Double PIS009 = currentMap.get("PIS009");//经营收入
		Double PIS018 = currentMap.get("PIS018");//事业支出
		Double PIS024 = currentMap.get("PIS024");//经营支出
		
		if(PIS005 != null && PIS009 !=null && PIS018 !=null&& PIS024 !=null && !isZero(PIS005 + PIS009))
			return (PIS005 + PIS009 - PIS018 - PIS024)/(PIS005+PIS009);
		else
			return null;
	}
	
	//	偿债率
	//TODO　
	public Double calculatePFR006(){
		return null;
	}
	
	//负债收入比率:负债合计/收入合计
	public Double calculatePFR007(){
		Double PBS041 = currentMap.get("PBS041");//负债合计
		Double PBS059 = currentMap.get("PBS059");//收入合计
		
		if(PBS041 != null && PBS059 != null && !isZero(PBS059)){
			return PBS041 / PBS059;
		}
		else return null;
	}
	
	
}
